package it.polito.let.http;

import it.polito.let.filesystem.FileUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public abstract class Responder {
	private Response response;

	public Responder() throws HTTPError {
		response = new Response("HTTP/1.1", (short) 200, "OK");
		response.setHeaderField("Content-Length", "0");
	}

	public abstract Request getRequest();

	public void setHeaderField(String fieldName, String fieldValue) throws HTTPError {
		response.setHeaderField(fieldName, fieldValue);
	}

	private void returnFile(String path) throws HTTPError {
		try {
			File file = new File(path);
			assertReadable(file);
			response.setHeaderField("Content-Length", String.valueOf(file.length()));
			response.setPayloadStream(new FileInputStream(file));
		} catch (IOException e) {
			throw new HTTPError((short) 500, "Internal Server Error");
		}
	}

	private void assertReadable(File file) throws HTTPError {
		if (file.isDirectory())
			throw new HTTPError((short) 403, "Forbidden");
		if (!file.isFile())
			throw new HTTPError((short) 404, "Not Found");
		if (!file.canRead())
			throw new HTTPError((short) 403, "Forbidden");
	}

	public void returnFileByExtension(String path) throws HTTPError {
		response.setHeaderField("Content-Type", HTTPConstants.convertExensionType(FileUtil.FileExtension(path)));
		returnFile(path);
	}

	/**	public void returnHTMLFile(String path) throws HTTPError {
		response.setHeaderField("Content-Type", "text/html");
		returnFile(path);
	}

	public void returnCSSStylesheet(String path) throws HTTPError {
		response.setHeaderField("Content-Type", "text/css");
		returnFile(path);
	}

	public void returnXMLFile(String path) throws HTTPError {
		response.setHeaderField("Content-Type", "text/xml");
		returnFile(path);
	}

	public void returnImageFile(String path) throws HTTPError {
		response.setHeaderField("Content-Type", "image/jpeg");
		returnFile(path);
	}

	public void returnJavascriptFile(String path) throws HTTPError {
		response.setHeaderField("Content-Type", "text/javascript");
		returnFile(path);
	}

	public void returnXMLStream(InputStream stream) throws HTTPError {
		response.setHeaderField("Content-Type", "text/xml");
		returnStream(stream);
	}*/

	public void returnStream(InputStream stream) throws HTTPError {
		try {
			response.setHeaderField("Content-Length", String.valueOf(stream.available()));
			response.setPayloadStream(stream);
		} catch (IOException e) {
			throw new HTTPError((short) 500, "Internal Server Error");
		}
	}

	public void returnRedirect(String url) throws HTTPError {
		response.setResponseCode((short) 303);
		response.setResponseMessage("See Other");
		response.setHeaderField("Location", url);
		response.setHeaderField("Content-Length", "0");
	}

	public Response getResponse() {
		return response;
	}

	public void throwHTTPError(short code, String msg, String additionalInfo) throws HTTPError {
		HTTPError e = new HTTPError(code, msg);
		if (e != null)
			e.addAdditionalInfo(additionalInfo);
		throw e;
	}

	public void throwHTTPError(short code, String msg) throws HTTPError {
		throwHTTPError(code, msg, null);
	}

	public void HTTPServerError(String msg) throws HTTPError {
		throwHTTPError((short)500, "Internal Server Error", msg);
	}
	public void HTTPServerError() throws HTTPError {
		throwHTTPError((short)500, "Internal Server Error", null);
	}
}